package com.liruan.rest.codegenerator;

import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.Date;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Objects;
import java.util.Set;

import com.liruan.rest.util.StringHelper;

public class POGenerator
{
	public static void generatePO(String tableName, String packageName, String ip, int port, String dbName, String user, String password, Class<?> enumClass)
	{
		String url = "jdbc:mysql://" + ip + ":" + port + "/" + dbName;
		String driver = "com.mysql.jdbc.Driver";
		try
		{
			Class.forName(driver);
			Connection con = DriverManager.getConnection(url, user, password);
			DatabaseMetaData meta = con.getMetaData();
			ResultSet rs = meta.getColumns(null, null, tableName, "%");
			StringBuilder builder = new StringBuilder();
			builder.append("package ").append(packageName).append(";");
			List<ColumnDetail> list = new LinkedList<>();
			Set<Class<?>> classRequired = new HashSet<>();
			while (rs.next())
			{
				ColumnDetail detail = new ColumnDetail();
				detail.columnName = StringHelper.underscoreToHumpStyle(rs.getString("COLUMN_NAME"), false);
				detail.comment = rs.getString("REMARKS");
				detail.comment = detail.comment == null ? detail.columnName : detail.comment;
				detail.columnType = detail.columnType = dbTypeToJavaType(rs.getString("TYPE_NAME"), enumClass);
				list.add(detail);
				classRequired.add(detail.columnType);
			}

			classRequired.forEach((cls) -> {
				String name = cls.getName();
				builder.append("import ").append(name).append(";");
			});

			String className = StringHelper.underscoreToHumpStyle(tableName, true);
			builder.append("public class ").append(className).append("PO").append(" {");

			list.forEach((column) -> {
				builder.append("\n").append("/**").append("\n").append("* ").append(column.comment).append("\n").append(
						"*/")
						.append("\n").append(column.columnType.getSimpleName()).append(" ").append(column.columnName)
						.append(";");
			});

			builder.append("}");
			System.out.println(builder.toString());
		}
		catch (Exception e)
		{
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}

	static class ColumnDetail
	{
		String columnName;
		String comment;
		Class<?> columnType;
	}

	private static Class<?> dbTypeToJavaType(String dbType, Class<?> enumClass)
	{
		dbType = dbType.toUpperCase();
		//		System.out.println(dbType);
		switch (dbType)
		{
		case "VARCHAR":
		case "VARCHAR2":
		case "CHAR":
			return String.class;
		case "NUMBER":
		case "DECIMAL":
			return Double.class;
		case "INT":
		case "SMALLINT":
		case "INTEGER":
		case "TINYINT":
			return Integer.class;
		case "BIGINT":
			return Long.class;
		case "DATETIME":
		case "TIMESTAMP":
			return LocalDateTime.class;
		case "DATE":
			return LocalDate.class;
		case "ENUM":
			if (Objects.isNull(enumClass) || !Enum.class.isAssignableFrom(enumClass))
			{
				return Object.class;
			}
			return enumClass;
		default:
			return Object.class;
		}
	}

	public static void main(String[] args)
	{
		generatePO("im_staff_status_transition_history", "com.msxf.bot.chat.dao.pojo", "10.250.140.196", 3306, "smartxma_im_chat",
				"smartxma", "smartxma", StaffStatus.class);
	}
}
